package com.atguigu.juc.cf;

import org.junit.jupiter.api.Test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author yanglin
 * @create 2024-01-05 10:42 星期五
 * description: 
 */
public class CompletableFutureFastDemo {


    /**
     * 比较两个异步任务 哪一个运行时间快
     */
    @Test
    public void testCompletableFutureFast() throws ExecutionException, InterruptedException {
        CompletableFuture<String> playA = CompletableFuture.supplyAsync(() -> {
            System.out.println("A come in");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "palyA";
        });

        CompletableFuture<String> playB = CompletableFuture.supplyAsync(() -> {
            System.out.println("B come in");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "palyB";
        });

        
        //比较两个异步任务 哪一个运行时间快
        CompletableFuture<String> result = playA.applyToEither(playB, f -> {
            return f + " is winner";
        });

        System.out.println(result.get());
    }


    /**
     * 对结果进行合并
     */
    @Test
    public void testCompletableFutureCombine(){
        CompletableFuture<Integer> task1 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 10;
        });

        CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 20;
        });

        CompletableFuture<Integer> res = task1.thenCombine(task2, (x, y) -> {
            System.out.println("开始合并两个异步任务的结果");
            return x + y;
        });

        System.out.println(res.join());
    }


    /**
     * 合并的一个小练习
     */
    @Test
    public void testCompletableFutureCombineDemo(){
        CompletableFuture<Integer> result = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + " come in 1");
            return 10;
        }).thenCombine(CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + " come in 2");
            return 20;
        }), (x, y) -> {
            System.out.println(Thread.currentThread().getName() + "\t" + " come in 3");
            return x + y;
        }).thenCombine(CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + " come in 4");
            return 30;
        }), (a, b) -> {
            System.out.println(Thread.currentThread().getName() + "\t" + " come in 5");
            return a + b;
        });

        System.out.println(result.join());
    }
    
}
